package test.verticle

import com.gitee.ixtf.vertx.verticle.BaseApiVerticle
import io.netty.handler.codec.compression.StandardCompressionOptions
import io.vertx.core.Future
import io.vertx.core.http.HttpServerOptions
import io.vertx.core.json.JsonObject
import io.vertx.ext.auth.oauth2.OAuth2Auth
import io.vertx.ext.healthchecks.HealthCheckHandler
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.HSTSHandler
import io.vertx.ext.web.handler.ResponseTimeHandler
import io.vertx.kotlin.core.http.httpServerOptionsOf
import io.vertx.kotlin.core.net.jksOptionsOf
import io.vertx.kotlin.coroutines.coAwait
import io.vertx.micrometer.PrometheusScrapingHandler
import jakarta.inject.Inject

class TestVerticle : BaseApiVerticle() {
  @Inject private lateinit var authFuture: Future<OAuth2Auth>
  override val graphQLWSAuth by lazy { authFuture }

  @ExperimentalStdlibApi
  override suspend fun start() {
    vertx
        .createHttpServer(
            httpServerOptionsOf(compressionSupported = true).apply {
              addWebSocketSubProtocol("graphql-transport-ws")
              addCompressor(StandardCompressionOptions.gzip())
              addCompressor(StandardCompressionOptions.deflate())
              // addCompressor(StandardCompressionOptions.brotli())
              // addCompressor(StandardCompressionOptions.zstd())
            })
        .requestHandler(
            Router.router(vertx).apply {
              route().failureHandler(failureHandler)
              route().handler(corsHandler)
              route().handler(bodyHandler)
              route().handler(ResponseTimeHandler.create())
              route().handler(HSTSHandler.create())
              this["/health"].handler(HealthCheckHandler.create(vertx))
              this["/metrics"].handler(PrometheusScrapingHandler.create())
              route().handler { rc ->
                val headers =
                    JsonObject(
                        buildMap {
                          val remoteAddress = rc.request().remoteAddress()
                          put("remoteAddress", remoteAddress.host())
                          put("117.147.2.116", remoteAddress.host())
                          rc.request().headers().forEach { (key, value) -> put(key, value) }
                        })
                rc.response().end(headers.toBuffer())
              }
            })
        .listen(port, host)
        .coAwait()
  }

  override suspend fun prepare(options: HttpServerOptions) {
    // options.isSsl = true
    options.isUseAlpn = true
    options.keyCertOptions =
        jksOptionsOf(
            alias = "server",
            password = "medipath888",
            value = fileSystem.readFileBlocking("keystore/keystore.jks"),
        )
  }
}
